package web

import (
	"net"
	"net/http"
)

// 确保HttpServer实现Server接口
var _ Server = &HttpServer{}

type HandleFunc func(ctx *Context)


// 只包含核心接口
type Server interface {
	http.Handler

	Start(addr string) error

	//添加路由
	addRoute(method string, path string, handlerFunc HandleFunc)
	// 我们并不采取这种设计方案
	// addRoute(method string, path string, handlers... HandleFunc)
}



type HttpServer struct{
	// addr string 创建的时候传递，而不是 Start 接收。这个都是可以的
	router
}

func NewHTTPServer() *HttpServer {
	return &HttpServer{
		router: newRouter(),
	}
}

//http.Handler接口中的方法  所有请求都经过这里
func (h *HttpServer) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
	// 你的框架代码就在这里
	ctx := &Context{
		Req: request,
		Resp: writer,
	}
	h.server(ctx)
}


func (h *HttpServer) server(ctx *Context){
	// 接下来就是查找路由，并且执行命中的业务逻辑
	mi, ok := h.findRoute(ctx.Req.Method, ctx.Req.URL.Path)
	if !ok || mi.n.handler == nil{
		ctx.Resp.WriteHeader(404)
		ctx.Resp.Write([]byte("Not Found"))
		return
	}
	ctx.PathParams = mi.pathParams
	mi.n.handler(ctx)
}


func (h *HttpServer) Start(addr string) error {
	if addr == "" {
		addr = ":http"
	}
	ln, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}

	// 在这里，可以让用户注册所谓的 after start 回调
	// 比如说往你的 admin 注册一下自己这个实例
	// 在这里执行一些你业务所需的前置条件

	return http.Serve(ln, h)
}

func (h *HttpServer) Get(path string, handler HandleFunc)  {
	h.addRoute(http.MethodGet, path, handler)
}

func (h *HttpServer) POST(path string, handler HandleFunc)  {
	h.addRoute(http.MethodPost, path, handler)
}





